package cc.telecomdigital.tdstock.Http.Services;

import java.io.IOException;
import java.net.SocketTimeoutException;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;

import android.content.Context;
import cc.telecomdigital.tdstock.Framework.UniqueItem.DeviceInfo;
import cc.telecomdigital.tdstock.Framework.UniqueItem.TDStockLog;
import cc.telecomdigital.tdstock.Http.H_CODE;
import cc.telecomdigital.tdstock.Services.CommunicTools;

/**
 * Send ilogin http request service obj
 * @author ouyangzhihui
 *
 */
public class H_ILoginAuthRequest extends H_SendTemplate
{
	public interface IH_ILoginAuthRequest_Report
	{
		void H_ILoginAuthRequest_Response(H_ILoginAuthRequest_Result iResult);
	}
	
	public class AuthStore
	{
		public String authAccount;
		public String authSeesionID;
		public String authSvcPlan;
		public String authSvcFlags;
//		public String authLoginName;
//		public String authLastLoginType;
//		public String authLocation;
//		public String authType;
//		public String authDeviceID;
//		public String authVersion;
		public String authStatus;
		public String authErrorMessage;
		public String authSportsPromotionMessage;
		public String authHorsePromotionMessage;
		
		public AuthStore()
		{
			authAccount = "";
			authSeesionID = "";
			authSvcPlan = "";
			authSvcFlags = "";
			authStatus = "";
			authErrorMessage = "";
			authSportsPromotionMessage= "";
			authHorsePromotionMessage = "";
		}
		
		public AuthStore(String iAuthAccount, String iAuthSessionID, String iAuthSvcPlan, String iAuthSvcFlags, String iAuthStatus, String iAuthErrorMessage)
		{
			authAccount = iAuthAccount;
			authSeesionID = iAuthSessionID;
			authSvcPlan = iAuthSvcPlan;
			authSvcFlags = iAuthSvcFlags;
			authStatus = iAuthStatus;
			authErrorMessage = iAuthErrorMessage;
		}
		
		public void SetPromotionMessage(String iSportsPromotionMessage, String iHorsePromotionMessage)
		{
			authSportsPromotionMessage = iSportsPromotionMessage;
			authHorsePromotionMessage = iHorsePromotionMessage;
		}
		
		public String ToString()
		{
			return authAccount+","+authSeesionID+","+authSvcPlan+","+authSvcPlan+","+authStatus+","+authErrorMessage+","+authSportsPromotionMessage+","+authHorsePromotionMessage;
		}
	}

	public class H_ILoginAuthRequest_Result extends H_GatewayResult
	{
		public AuthStore	authStore;
		public String		HErrorMessage;

		public H_ILoginAuthRequest_Result()
		{
			super();
			authStore = new AuthStore();
			HErrorMessage = "";
		}

		public void SetAuthResult(AuthStore iAuthStore)
		{
			authStore = iAuthStore;
		}

		public void SetHErrorMessage(String iErrorMessage)
		{
			if (iErrorMessage != null)
				iErrorMessage = iErrorMessage.trim();
			HErrorMessage = iErrorMessage;
		}
	}

	private IH_ILoginAuthRequest_Report	handler;

	public H_ILoginAuthRequest(Context iCaller)
	{
		super(iCaller);
		handler = null;
	}

	public H_CODE SubmitRequest(final String urlString, IH_ILoginAuthRequest_Report iHandler)
	{
		H_CODE status;
		status = H_CODE.OK;
		
//		if(!DeviceInfo.IsNetworkAvailable(callerContext))
//			return H_CODE.NO_NETWORK;
		
		handler = iHandler;

		Thread internalThreadObj = new Thread()
		{
			@Override
			public void run()
			{
				HttpGet targetGet;
				HttpClient targetClient;
				H_ILoginAuthRequest_Result requestResult;
				
				targetGet = GetHttpGet(urlString);
				targetClient = GetDefaultHttpClient();
				
				if ((!DeviceInfo.IsNetworkAvailable(callerContext)) || (targetGet == null) || (targetClient == null))
				{
					String resultCode;
					String resultString;
					// Our custom define error, in the Send Parent Template, positive allow a retry
					resultCode = "1";
					resultString = GetInnerErrorMessage(resultCode);
					requestResult = new H_ILoginAuthRequest_Result();
					requestResult.SetGateWayStatus(resultCode, resultString);
					
					if (debugMode)
						TDStockLog.i(GetIdentity(), "Error: " + resultCode + ", " + resultString);

					if (handler != null)
						handler.H_ILoginAuthRequest_Response(requestResult);

					return;
				}

				int trialCount;
				trialCount = 0;
				while (true)
				{
					requestResult = SendDataSub(targetClient, targetGet);
					// If we did not get the require recall information, might or might not retry
					if (requestResult.MStatus.length() == 0)
					{
						++trialCount;
						if (trialCount < trialMax)
						{
							if (debugMode)
								TDStockLog.i(GetIdentity(), "SubmitRequest: Retry performed: " + trialCount);
							try
							{
								sleep(RETRY_DELAY_TIME);
							}
							catch (Exception ex)
							{
								TDStockLog.e(GetIdentity(), "SubmitRequest=>Exception=" + ex.toString());
								ex.printStackTrace();
							}
							continue;
						}
					}
					break;
				}

				// We have try but we have no reply
				if (requestResult.MStatus.length() == 0)
				{
					String resultCode;
					String resultString;
					//
					resultCode = "-2";
					resultString = GetInnerErrorMessage(resultCode);
					requestResult = new H_ILoginAuthRequest_Result();
					requestResult.SetGateWayStatus(resultCode, resultString);
				}

				if (debugMode)
					TDStockLog.i(GetIdentity(), "Error: " + requestResult.MStatus + ", " + requestResult.MError);

				if (handler != null)
					handler.H_ILoginAuthRequest_Response(requestResult);
			}
		};

		internalThreadObj.start();

		return status;
	}
	
	private H_ILoginAuthRequest_Result SendDataSub(HttpClient iClient, HttpGet iGetURL) 
	{
		H_ILoginAuthRequest_Result reqResult;
		HttpResponse		   response;
		String                 MErrorStatus, MErrorMessage;

		reqResult = new H_ILoginAuthRequest_Result();
		try
		{
			StatusLine httpStatus;

			synchronized(logonLock)
			{
				response = iClient.execute(iGetURL);
			}
			
			httpStatus = response.getStatusLine();
			
			TDStockLog.d("TAG", "HttpStatus: "+httpStatus.getStatusCode()+","+httpStatus.getReasonPhrase());
			
			//Close the connection if not reachable or others, usually not happen
			if (httpStatus.getStatusCode() != HttpStatus.SC_OK)
			{
				response.getEntity().getContent().close();
				return reqResult;
			}

			//prepare for the result			
			String sessionKey, accountNo, statCode, errorMsg;
			String svcPlan, svcFlags, sportMsg, horseMsg;
			
			sessionKey = "";
			accountNo = "";
			statCode = "";
			errorMsg = "";
			svcPlan = "";
			svcFlags = "";
			sportMsg = "";
			horseMsg = "";
			//Now perform the sending and obtaining the expected data		
			StringBuffer contentString;
			contentString = CommunicTools.GetWebResponseInStringBuffer(response);						
			
			sessionKey = CommunicTools.FindXMLStringContent(contentString, "SessionID");
			accountNo  = CommunicTools.FindXMLStringContent(contentString, "Account");	
//			0 Success
//			1 invalid account.
//			2 invalid svc_no
//			3 invalid status
//			4 invalid login_name or account
//			5 invalid password
//			6 invalid model
//			7 invalid charge
//			9 SQL Exception
			statCode = CommunicTools.FindXMLStringContent(contentString, "Status");
			errorMsg = CommunicTools.FindXMLStringContent(contentString, "ErrorMessage");

			svcPlan  = CommunicTools.FindXMLStringContent(contentString, "SvcPlan");
			svcFlags = CommunicTools.FindXMLStringContent(contentString, "SvcFlags");
			sportMsg = CommunicTools.FindXMLStringContent(contentString, "SportsPromotionMessage");
			horseMsg = CommunicTools.FindXMLStringContent(contentString, "HorsePromotionMessage");
			
			AuthStore contentStore = new AuthStore(accountNo, sessionKey, svcPlan, svcFlags, statCode, errorMsg);
			contentStore.SetPromotionMessage(sportMsg, horseMsg);
			reqResult.MStatus = contentStore.authStatus;
			reqResult.HErrorMessage = contentStore.authErrorMessage;
			reqResult.SetAuthResult(contentStore);
		}
		catch(SocketTimeoutException e)
		{
			e.printStackTrace();
			TDStockLog.e(GetIdentity(), "SendDataSub=>SocketTimeoutException: " + e.toString());
			
			MErrorStatus  = "-12";
			MErrorMessage = GetInnerErrorMessage(MErrorStatus);
			reqResult.SetGateWayStatus(MErrorStatus, MErrorMessage);
		}
		catch (ClientProtocolException e)
		{
			e.printStackTrace();
			TDStockLog.e(GetIdentity(), "SendDataSub=>ClientProtocolException: " + e.toString());
			
			MErrorStatus  = "-2";
			MErrorMessage = GetInnerErrorMessage(MErrorStatus);
			reqResult.SetGateWayStatus(MErrorStatus, MErrorMessage);
		}
		catch (IOException e)
		{
			e.printStackTrace();
			TDStockLog.e(GetIdentity(), "SendDataSub=>IOException: " + e.toString());
			
			MErrorStatus  = "-2";
			if(e.toString().toUpperCase().contains("SocketTimeout".toUpperCase()))
				MErrorStatus = "-12";
			else if(e.toString().toUpperCase().contains("Timeout".toUpperCase()))
				MErrorStatus = "-11";
			
			MErrorMessage = GetInnerErrorMessage(MErrorStatus);
			reqResult.SetGateWayStatus(MErrorStatus, MErrorMessage);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			TDStockLog.e(GetIdentity(), "SendDataSub=>Exception: " + e.toString());
			
			MErrorStatus  = "-2";
			if(e.toString().toUpperCase().contains("SocketTimeout".toUpperCase()))
				MErrorStatus = "-12";
			else if(e.toString().toUpperCase().contains("Timeout".toUpperCase()))
				MErrorStatus = "-11";
			
			MErrorMessage = GetInnerErrorMessage(MErrorStatus);
			reqResult.SetGateWayStatus(MErrorStatus, MErrorMessage);
		}
		
		return reqResult;
	}
}
